package com.eff.android.fragment;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.eff.android.fragment.main.EMainFragment;
import com.eff.android.fragment.main.EMainFragmentIntroduction;
import com.eff.android.fragment.main.start.EMainFragmentPronounciation;
import com.eff.android.fragment.options.EMainFragmentOptions;
import com.eff.android.fragment.options.EMainFragmentOptionsSubjects;

import android.os.Bundle;
import android.support.v4.app.Fragment;

public class EFragmentFactory {
	
	static Map<String, Type> registered = new HashMap<String, Type>();
	static Map<String, Fragment> load = new HashMap<String, Fragment>();
	
	static EFragmentFactory factory = new EFragmentFactory();
	
	public static EFragmentFactory newInstance(){
		if (factory != null)
			factory = new EFragmentFactory();
		
		factory.Register(EMainFragment.TAG, EMainFragment.class);
		factory.Register(EMainFragmentPronounciation.TAG, EMainFragmentPronounciation.class);
		factory.Register(EMainFragmentIntroduction.TAG, EMainFragmentIntroduction.class);
		factory.Register(EMainFragmentOptions.TAG, EMainFragmentOptions.class);
		factory.Register(EMainFragmentOptionsSubjects.TAG, EMainFragmentOptionsSubjects.class);
		
		return factory;
	}
	
	private static void Load(Bundle arguments){
		Set<Entry<String, Type>> entrySet = registered.entrySet();
		for (Map.Entry<String, Type> entry : entrySet){
			
			if (!load.containsKey(entry.getKey())){
				try {
					Constructor constructor = ((Class)entry.getValue()).getConstructor(Bundle.class);
					load.put(entry.getKey(), (Fragment)constructor.newInstance(arguments));
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	public void Register(String tag, Type type)
	{
		registered.put(tag, type);
	}
	
	public Fragment CreateFragment(String type, Bundle arguments){
		if (load.get(type) == null){
			Load(arguments);
		}
		
		return load.get(type);
	}

	public Fragment CreateFragment(String type){
		if (load.get(type) == null){
			Load(null);
		}
		
		return load.get(type);
	}

}
